package com.wwdx.shiro;

import com.wwdx.utils.ConstantHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * 保存最新的用户在线，踢出上一个用户
 * @author liguoliang
 */
public class KeepOneSessionControlFilter extends AccessControlFilter {

    private SessionManager sessionManager;
    private RedisTemplate<String,String> redisTemplate;

    public KeepOneSessionControlFilter(SessionManager sessionManager, RedisTemplate<String, String> redisTemplate) {
        this.sessionManager = sessionManager;
        this.redisTemplate = redisTemplate;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
        Integer userId = SessionUser.getUserId();
        // 没有登录
        if (userId == null) {
            return true;
        }
        //当前会话
        Session session = SessionUser.getSession();
        if (session != null){
            String sessionId = session.getId().toString();
            ValueOperations<String,String> valueOperations = redisTemplate.opsForValue();
            //当前用户缓存中的sessionId
            String userKeepOne = String.format(ConstantHolder.USER_KEEPONE, userId);
            String deleteSessionId = valueOperations.get(userKeepOne);
            if (sessionId.equalsIgnoreCase(deleteSessionId)) {
                return true;
            } else if(StringUtils.isBlank(deleteSessionId)){
                valueOperations.set(userKeepOne, sessionId);
                return true;
            }else {
                valueOperations.set(userKeepOne, sessionId);
                Session deletetSession = null;
                try {
                    deletetSession = sessionManager.getSession(new DefaultSessionKey(deleteSessionId));
                } catch (UnknownSessionException e) {
                    //no session with  id [deleteSessionId]
                }

                if (deletetSession == null) {
                    return true;
                }

                //根据 需要删除的 sessionId,生成subject
                Subject deleteSubject = new Subject.Builder().sessionId(deleteSessionId).buildSubject();
                //退出
                deleteSubject.logout();
                //在此可以自定义json格式的回复
                return true;
            }
        }
        return false;
    }
}